package com.hhkj.study.admin.dict.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.hhkj.study.admin.dict.common.LevelCodeEnum;
import com.hhkj.study.admin.dict.entity.DictMultiLevel;
import com.hhkj.study.admin.dict.model.podo.DictMultiLevelDo;
import com.hhkj.study.admin.dict.model.podo.DictMultiLevelPo;
import com.hhkj.study.admin.dict.model.req.DictMultiLevelReq;
import com.hhkj.study.admin.dict.model.res.DictMultiLevelTreeListRes;
import com.hhkj.study.admin.dict.model.res.DictMultiLevelRes;
import com.hhkj.study.admin.dict.service.base.DictMultiLevelService;
import com.hhkj.study.admin.dict.service.biz.DictMultiLevelBizService;
import com.hhkj.study.admin.dict.service.extend.DictMultiLevelExtendService;
import com.hhkj.study.common.cache.GlobalCache;
import com.hhkj.study.common.handler.CommonHandler;
import com.ruoyi.common.base.biz.service.biz.BaseBizServiceImpl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.cont.SysConst;
import com.ruoyi.common.enums.DictCodeEnum;
import com.ruoyi.common.exception.GlobalException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
* DictMultiLevelBizServiceImpl
*
* @author SERVER
* @since 2024-09-06
*/
@Service
public class DictMultiLevelBizServiceImpl extends BaseBizServiceImpl<DictMultiLevel, DictMultiLevelReq, DictMultiLevelRes, DictMultiLevelDo, DictMultiLevelPo, DictMultiLevelService, DictMultiLevelExtendService> implements DictMultiLevelBizService {

    @Resource
    private GlobalCache globalCache;

    @Override
    protected void beforeSave(DictMultiLevelReq dictMultiLevelReq) {
        // 通过父id默认设置层级
        if (Constants.TOP_PARENT_ID.equals(dictMultiLevelReq.getParentId())) {
            dictMultiLevelReq.setLevelCode(LevelCodeEnum.TOP.getCode());
            if (StrUtil.isBlank(dictMultiLevelReq.getTypeCode())) {
                throw new GlobalException("最顶层元素字典类型code不能为空");
            }
        } else {
            DictMultiLevel dictMultiLevel = this.getExtendService().getByIdNotNull(dictMultiLevelReq.getParentId());
            dictMultiLevelReq.setLevelCode(Objects.requireNonNull(LevelCodeEnum.getNextByCode(dictMultiLevel.getLevelCode())).getCode());
            dictMultiLevelReq.setTypeCode(dictMultiLevel.getTypeCode());
        }

        // 考试动态模块 extendId和extendType不能为空
        if (StrUtil.equalsIgnoreCase(DictCodeEnum.EXAM_TREND.getCode(), dictMultiLevelReq.getTypeCode())) {
            if (CollectionUtil.isEmpty(dictMultiLevelReq.getExtendIdList())) {
                throw new GlobalException("所选区域不能为空");
            }
            if (CollectionUtil.isEmpty(dictMultiLevelReq.getExtendTypeList())) {
                throw new GlobalException("课程类型不能为空");
            }
        }
        super.beforeSave(dictMultiLevelReq);
    }

    @Override
    protected void afterSave(DictMultiLevelReq req) {
        globalCache.asyncRemoveCachePrefix(req.getTypeCode());
    }

    @Override
    protected void afterList(List<DictMultiLevelRes> dictMultiLevelResList) {
        if (CollectionUtil.isEmpty(dictMultiLevelResList)) {
            return;
        }

        // 父id下所有的数据 通过父id分组,组装成父id和父类id所有内容拼接
        List<Long> dictIdList = dictMultiLevelResList.stream().map(DictMultiLevelRes::getId).collect(Collectors.toList());
        LambdaQueryWrapper<DictMultiLevel> dictQuery = new LambdaQueryWrapper<>();
        dictQuery.in(DictMultiLevel::getParentId, dictIdList);
        dictQuery.in(DictMultiLevel::getDisableFlag, SysConst.Flag.NO.getFlag());
        List<DictMultiLevel> dictMultiLevelList = this.getService().list(dictQuery);
        if (CollectionUtil.isEmpty(dictMultiLevelList)) {
            return;
        }
        Map<Long, String> parentIdNameMap = dictMultiLevelList.stream().collect(Collectors.groupingBy(DictMultiLevel::getParentId, Collectors.mapping(DictMultiLevel::getName, Collectors.joining("|"))));
        dictMultiLevelResList.forEach(res -> {
            if (!Constants.TOP_PARENT_ID.equals(res.getParentId())) {
                return;
            }
            res.setContent(parentIdNameMap.get(res.getId()));
        });
    }

    @Override
    protected void afterUpdate(DictMultiLevelReq req) {
        DictMultiLevel dictMultiLevel = this.getExtendService().getByIdNotNull(req.getId());
        globalCache.asyncRemoveCachePrefix(dictMultiLevel.getTypeCode());
    }

    @Override
    protected void afterPage(List<DictMultiLevelRes> dictMultiLevelResList) {
        Map<Long, String> dictMap = globalCache.cacheDictMap(Constants.REGION_COURSE_CODE_LIST);
        dictMultiLevelResList.forEach(dictMultiLevelRes -> {
            dictMultiLevelRes.setExtendIdValue(CommonHandler.joinStr(dictMap, dictMultiLevelRes.getExtendIdList(), Constants.VERTICAL_LINE));
            dictMultiLevelRes.setExtendIdMap(CommonHandler.getMapByDict(dictMap, dictMultiLevelRes.getExtendIdList()));
            dictMultiLevelRes.setExtendTypeValue(CommonHandler.joinStr(dictMap, dictMultiLevelRes.getExtendTypeList(), Constants.VERTICAL_LINE));
            dictMultiLevelRes.setExtendTypeMap(CommonHandler.getMapByDict(dictMap, dictMultiLevelRes.getExtendTypeList()));
        });
    }



    @Override
    public List<DictMultiLevelTreeListRes> listTreeAll(DictMultiLevelReq req) {
        LambdaQueryWrapper<DictMultiLevel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DictMultiLevel::getTypeCode, req.getTypeCode());
        queryWrapper.like(StrUtil.isNotBlank(req.getName()), DictMultiLevel::getName, req.getName());
        queryWrapper.orderByAsc(DictMultiLevel::getOrderNum);
        List<DictMultiLevel> entityList = this.getService().list(queryWrapper);
        if (CollectionUtil.isEmpty(entityList)) {
            return Lists.newArrayList();
        }
        List<DictMultiLevelTreeListRes> resList = BeanUtil.copyToList(entityList, DictMultiLevelTreeListRes.class);
        Map<Long, String> dictMap = globalCache.cacheDictMap(Constants.REGION_COURSE_CODE_LIST);
        resList.forEach(res -> {
            if (CollectionUtil.isNotEmpty(res.getExtendIdList())) {
                res.setExtendIdValue(CommonHandler.joinStr(dictMap, res.getExtendIdList(), Constants.VERTICAL_LINE));
                res.setExtendIdMap(CommonHandler.getMapByDict(dictMap, res.getExtendIdList()));
            }
            if (CollectionUtil.isNotEmpty(res.getExtendTypeList())) {
                res.setExtendTypeValue(CommonHandler.joinStr(dictMap, res.getExtendTypeList(), Constants.VERTICAL_LINE));
                res.setExtendTypeMap(CommonHandler.getMapByDict(dictMap, res.getExtendTypeList()));
            }
        });
        Map<Long, List<DictMultiLevelTreeListRes>> resListGroupByParentId = resList.stream()
                .collect(Collectors.groupingBy(DictMultiLevelTreeListRes::getParentId));
        for (DictMultiLevelTreeListRes res : resList) {
            if (resListGroupByParentId.containsKey(res.getId())) {
                res.setChildren(resListGroupByParentId.get(res.getId()));
            }
        }
        return resList.stream().filter(res -> LevelCodeEnum.SECOND.getCode().equals(res.getLevelCode())).collect(Collectors.toList());
    }

    @Override
    public boolean updateDisableFlag(DictMultiLevelReq req) {
        if (!DictCodeEnum.NOT_NEED_PUSHISHED_FLAG_CODE_LIST.contains(req.getTypeCode())) {
            if (ObjectUtil.isNull(req.getDisableFlag())) {
                throw new GlobalException("禁用启用状态不能为空");
            }
        }
        DictMultiLevel dictMultiLevel = this.getExtendService().getByIdNotNull(req.getId());
        if (dictMultiLevel.getDisableFlag().equals(req.getDisableFlag())) {
            throw new GlobalException(SysConst.Flag.IS.getFlag().equals(req.getDisableFlag()) ?
                    "已禁用" : "已启用");
        }
        LambdaUpdateWrapper<DictMultiLevel> dictUpdate = new LambdaUpdateWrapper<>();
        dictUpdate.eq(DictMultiLevel::getId, req.getId())
                .set(DictMultiLevel::getDisableFlag, req.getDisableFlag());
        boolean isSuccess = this.getService().update(dictUpdate);
        if (isSuccess) {
            // 异步删除缓存
            globalCache.asyncRemoveCachePrefix(req.getTypeCode());
        }
        return isSuccess;
    }

    @Override
    protected void beforeRemove(List<Long> idList) {
        List<DictMultiLevel> dictMultiLevelList = this.getService().listByIds(idList);
        if (CollectionUtil.isEmpty(dictMultiLevelList)) {
            return;
        }
        Set<String> typeCodeSet = dictMultiLevelList.stream().map(DictMultiLevel::getTypeCode).collect(Collectors.toSet());
        typeCodeSet.forEach(typeCode -> {
            // 异步删除缓存
            globalCache.asyncRemoveCachePrefix(typeCode);
        });
    }
}